package com.comment.pojo.domain.logic.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
import com.comment.pojo.domain.EquipAttribute;
import com.comment.pojo.domain.logic.core.CoreHero;
import com.comment.pojo.domain.logic.core.CoreHeroStar;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 游戏账户武将数据
 *
 * @author cxy
 * @since 2024-08-07 19:29:35
 */
@Slf4j
@ApiModel("游戏账户武将数据")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
@TableName(autoResultMap = true)
public class PlayerHero extends Model<PlayerHero> {// swagger2,mybatis-plus
    ///////////////////////////////////////////////////////////////////////////////////////////////////////// 生成实体字段
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键")
    private Long id;

    @NotNull
    @ApiModelProperty("账号uid")
    private Long uid;

    @ApiModelProperty("武将id")
    private Long coreHeroId;

    @ApiModelProperty("玩家命名")
    private String name;

    @ApiModelProperty("等级")
    private Integer level;

    @ApiModelProperty("当前经验")
    public Long currentExp;

    @ApiModelProperty("下一级需要的经验")
    private Long nextExp;

    @ApiModelProperty("武力")
    private Double att;

    @ApiModelProperty("防御")
    private Double def;

    @ApiModelProperty("智力")
    private Double magic;

    @ApiModelProperty("先攻值")
    private Double speed;

    @ApiModelProperty("统帅")
    private Double des;

    @ApiModelProperty("当前兵力")
    private Long currentForce;

    @ApiModelProperty("0:防守,1:进攻")
    private Integer rankCamp;

    @ApiModelProperty("所处队伍的序号")
    private Integer rankNo;

    @ApiModelProperty("所处队伍的顺序")//("武将防守位置 1 前锋 2 中军 3 大营")
    private Integer rankOrder;

    @ApiModelProperty("装备卡槽1")
    private Long equipSlot1;

    @ApiModelProperty("装备卡槽2")
    private Long equipSlot2;

    @ApiModelProperty("天赋技能信息")
    private Long skill;

    @TableField(typeHandler = Fastjson2TypeHandler.class)
    @ApiModelProperty("技能卡槽1")
    private Map<Integer, Long> skillSlot;

    @ApiModelProperty("技能卡槽1")
    private Long skillSlot1;

    @ApiModelProperty("技能卡槽2")
    private Long skillSlot2;

    @ApiModelProperty("星阶")
    private Integer star;

    @ApiModelProperty("稀有度")
    private Integer quality;

    ///////////////////////////////////////////////////////////////////////////////////////////////////////// 序列化版本号
    @TableField(exist = false)
    private static final long serialVersionUID = 437850302065134008L;


    /////////////////////////////////////////////////////////////////////////////////////////////////////////// 获取主键值
    @Override
    public Serializable pkVal() {
        return this.getId();
    }


    /////////////////////////////////////////////////////////////////////////////////////////////////////////    领域业务
    //////////////////////////////////////////////////////////////////////////////////////////////// 武将培养

    public static PlayerHero equip(
            @NotNull(message = "武将不能为空") PlayerHero playerHero,
            EquipAttribute equip
    ) {
        if (equip != null) {
            playerHero.setAtt(playerHero.getAtt() + equip.getAttack() / 100.0);
            playerHero.setDef(playerHero.getDef() + equip.getDefense() / 100.0);
            playerHero.setMagic(playerHero.getMagic() + equip.getMagic() / 100.0);
            playerHero.setSpeed(playerHero.getSpeed() + equip.getSpeed() / 100.0);
            playerHero.setDes(playerHero.getDes() + equip.getCommand() / 100.0);
            Integer equipSlot = equip.getSlot();
            if (equipSlot == 1) {
                playerHero.setEquipSlot1(equip.getId());
            }
            if (equipSlot == 2) {
                playerHero.setEquipSlot2(equip.getId());
            }
        }
        return playerHero;
    }

    public static PlayerHero unEquip(
            @NotNull(message = "武将不能为空") PlayerHero playerHero,
            EquipAttribute equip
    ) {
        if (equip != null) {
            playerHero.setAtt(playerHero.getAtt() - equip.getAttack() / 100.0);
            playerHero.setDef(playerHero.getDef() - equip.getDefense() / 100.0);
            playerHero.setMagic(playerHero.getMagic() - equip.getMagic() / 100.0);
            playerHero.setSpeed(playerHero.getSpeed() - equip.getSpeed() / 100.0);
            playerHero.setDes(playerHero.getDes() - equip.getCommand() / 100.0);
            Integer equipSlot = equip.getSlot();
            if (equipSlot == 1) {
                playerHero.setEquipSlot1(0L);
            }
            if (equipSlot == 2) {
                playerHero.setEquipSlot2(0L);
            }
        }
        return playerHero;
    }


    public void recalculateAttributes1
            (
                    CoreHero coreHero,
                    CoreHeroStar coreHeroStar
            ) {
        Integer level = getLevel() - 1;

        // att
        setAtt(coreHero.getInitAtt() + coreHeroStar.getAttGrowth() * level / 100.0);
        // def
        setDef(coreHero.getInitDef() + coreHeroStar.getDefGrowth() * level / 100.0);
        // magic
        setMagic(coreHero.getInitMagic() + coreHeroStar.getMagicGrowth() * level / 100.0);
        // speed
        setSpeed(coreHero.getInitSpeed() + coreHeroStar.getSpeedGrowth() * level / 100.0);
        // des
        setDes(coreHero.getInitCommand() + coreHeroStar.getCommandGrowth() * level / 100.0);
    }

    /**
     * 重新计算属性
     *
     * @param playerHero
     * @param coreHero
     * @param coreHeroStar
     */
    public static void recalculateAttributes
    (
            PlayerHero playerHero,
            CoreHero coreHero,
            CoreHeroStar coreHeroStar
    ) {
        Integer level = playerHero.getLevel() - 1;

        // att
        playerHero.setAtt(coreHero.getInitAtt() + coreHeroStar.getAttGrowth() * level / 100.0);
        // def
        playerHero.setDef(coreHero.getInitDef() + coreHeroStar.getDefGrowth() * level / 100.0);
        // magic
        playerHero.setMagic(coreHero.getInitMagic() + coreHeroStar.getMagicGrowth() * level / 100.0);
        // speed
        playerHero.setSpeed(coreHero.getInitSpeed() + coreHeroStar.getSpeedGrowth() * level / 100.0);
        // des
        playerHero.setDes(coreHero.getInitCommand() + coreHeroStar.getCommandGrowth() * level / 100.0);
    }


    // 战斗消息
    @ApiModelProperty("技能")
    @TableField(exist = false)
    private Set<Long> skillStarIds;

    public Set<Long> getSkillStarIds() {
        Set<Long> back = new HashSet<>();
        if (this.skill != null) {
            back.add(this.skill);
        } else {
            this.skill = 0L;
        }
        if (this.skillSlot1 != null) {
            back.add(this.skillSlot1);
        } else {
            this.skillSlot1 = 0L;
        }
        if (this.skillSlot2 != null) {
            back.add(this.skillSlot2);
        } else {
            this.skillSlot2 = 0L;
        }
        back.remove(0L);
        return back;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////    领域业务

    public void clear() {
        currentForce = 0L;
        rankOrder = 0;
        rankNo = 0;
    }

    public void addCurrentForce(Long num) {
        this.currentForce += num;
    }
}

